package cn.net.dckj.modules.pay.web;

import cn.net.dckj.common.pay.alipay.api.AliPayApi;
import cn.net.dckj.common.pay.alipay.api.AliPayApiConfig;
import cn.net.dckj.common.pay.alipay.api.AliPayApiController;
import cn.net.dckj.common.pay.alipay.model.AliPayConfig;
import cn.net.dckj.modules.biz.entity.BizEcsOrder;
import cn.net.dckj.modules.biz.service.BizEcsOrderService;
import cn.net.dckj.modules.cms.entity.Site;
import cn.net.dckj.modules.cms.utils.CmsUtils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

@Controller
@RequestMapping(value = "${adminPath}/pay/aliPay")
public class AliPayController extends AliPayApiController {

    @Autowired
    private AliPayConfig aliPayConfig;
    @Autowired
    private BizEcsOrderService bizEcsOrderService;

    @Override
    public AliPayApiConfig getApiConfig() {
        return AliPayApiConfig.New()
                .setServiceUrl(aliPayConfig.getGatewayUrl())
                .setAppId(aliPayConfig.getAppId())
                .setAlipayPublicKey(aliPayConfig.getPublicKey())
                .setCharset(aliPayConfig.getCharset())
                .setPrivateKey(aliPayConfig.getPrivateKey())
                .setFormat(aliPayConfig.getFormat())
                .setSignType(aliPayConfig.getSignType())
                .build();
    }

    /**
     * PC支付
     */
    @RequestMapping(value = "/pcPay")
    @ResponseBody
    public void pcPayJson(BizEcsOrder bizEcsOrder, HttpServletRequest request, HttpServletResponse response) {
        try {
            //设置请求参数
            String returnUrl = aliPayConfig.getDomain() + request.getContextPath() + "/test/return_url.jsp";
            String notifyUrl = aliPayConfig.getDomain() + request.getContextPath() + "/test/notify_url.jsp";
            returnUrl = aliPayConfig.getDomain() + request.getContextPath() + adminPath + "/pay/aliPay/return_url";
            notifyUrl = aliPayConfig.getDomain() + request.getContextPath() + adminPath + "/pay/aliPay/notify_url";
            // 商户订单号,64个字符以内、可包含字母、数字、下划线；需保证在商户端不重复
            String outTradeNo = bizEcsOrder.getId();
            // 销售产品码，与支付宝签约的产品码名称。注：目前仅支持FAST_INSTANT_TRADE_PAY
            String productCode = "FAST_INSTANT_TRADE_PAY";
            // 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]。
            String totalAmount = String.valueOf(bizEcsOrder.getMealPrice());
            // 订单标题
            String subject = bizEcsOrder.getMealName();
            // 订单描述，可选
            String body = bizEcsOrder.getRemarks();
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.setOutTradeNo(outTradeNo);
            model.setProductCode(productCode);
            model.setTotalAmount(totalAmount);
            model.setSubject(subject);
            model.setBody(body);
            model.setPassbackParams("passback_params");
            AliPayApi.tradePage(response, model, notifyUrl, returnUrl);
        } catch (Exception e) {
            renderString(response, e.getMessage());
        }
    }

    @RequestMapping(value = "/return_url")
    public String return_url(Model model, HttpServletRequest request) {
        String out_trade_no = "";
        String total_amount = "";
        try {
            // 获取支付宝GET过来反馈信息
            Map<String, String> map = AliPayApi.toMap(request);
            /*for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }*/
            out_trade_no = map.get("out_trade_no");
            total_amount = map.get("total_amount");
            boolean verify_result = AlipaySignature.rsaCheckV1(map,
                    aliPayConfig.getPublicKey(), aliPayConfig.getCharset(), aliPayConfig.getSignType());
            if (verify_result) { // 验证成功
                // TODO 请在这里加上商户的业务逻辑程序代码
                System.out.println("return_url 验证成功");
                String sellerId = map.get("seller_id");
                String tradeNo = map.get("trade_no");
                Double price = Double.parseDouble(total_amount);
                BizEcsOrder bizEcsOrder = bizEcsOrderService.get(out_trade_no);
                bizEcsOrder.setPrice(price);
                bizEcsOrder.setSellerId(sellerId);
                bizEcsOrder.setTradeNo(tradeNo);
                bizEcsOrder.setOrderFlag("2");
                bizEcsOrder.setPayType("1");
                bizEcsOrder.setPayTime(new Date());
                bizEcsOrderService.save(bizEcsOrder);
                Site site = CmsUtils.getSite(Site.defaultSiteId());
                model.addAttribute("site", site);
                model.addAttribute("bizEcsOrder", bizEcsOrder);
                return "modules/cms/front/themes/basic/paySuccess";
            } else {
                System.out.println("return_url 验证失败");
                // TODO
                model.addAttribute("out_trade_no", out_trade_no);
                model.addAttribute("message", "return_url 验证失败");
                return "modules/cms/front/themes/basic/payFailure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            model.addAttribute("out_trade_no", out_trade_no);
            model.addAttribute("total_amount", total_amount);
            model.addAttribute("pay_type", "1");
            model.addAttribute("pay_time", new Date());
            model.addAttribute("message", e.getMessage());
            return "modules/cms/front/themes/basic/payFailure";
        }
    }

    @RequestMapping(value = "/notify_url")
    @ResponseBody
    public String notify_url(HttpServletRequest request) {
        String out_trade_no = "";
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            /*for (Map.Entry<String, String> entry : params.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }*/
            out_trade_no = params.get("out_trade_no");
            boolean verify_result = AlipaySignature.rsaCheckV1(params,
                    aliPayConfig.getPublicKey(), aliPayConfig.getCharset(), aliPayConfig.getSignType());
            if (verify_result) { // 验证成功
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                System.out.println("notify_url 验证成功succcess");
                BizEcsOrder bizEcsOrder = bizEcsOrderService.get(out_trade_no);
                if (!"2".equals(bizEcsOrder.getOrderFlag())) {
                    String total_amount = params.get("total_amount");
                    Double price = Double.parseDouble(total_amount);
                    bizEcsOrder.setPrice(price);
                    bizEcsOrder.setOrderFlag("2");
                    bizEcsOrderService.save(bizEcsOrder);
                }
                return "success";
            } else {
                System.out.println("notify_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }
}
